<template>
  <div class="source-img" :class="{'list-top': info}" :style="{display: block, margin: margin}">
    <!--显示默认图片-->
    <div class="source-icon" :style="{width: width, height: height}" v-if="!item || isConstData">
      <img style="width: 100%; height: 100%" :src="`${$site.libServer}/front/notice_default.jpg`"/>
    </div>

    <!--显示服务端文件-->
    <div v-else class="clear">

      <!--显示图片-->
      <div
        ref="image"
        class="relative"
        v-if="item.type === 1"
        style="overflow: hidden"
        :style="{width: imgWidth || width, height: imageSourceHeight}">
        <img src="../../assets/img/view.png" class="viewPosition" v-if="isPort">
        <img
          class="preview-img"
          @load="imgOnload"
          @click="preview(item)"
          :style="{width: clientWidth, height: clientHeight, 'margin-top': clientTop, 'margin-left': clientLeft, cursor: isPropsPreview ? 'zoom-in' : 'normal'}"
          :src="src"/>
      </div>

      <!--显示音频文件-->
      <zz-sound :soundSrc="soundSrc" v-else-if="item.type === 2"></zz-sound>

      <!--显示视频文件-->
      <div :style="{
         display: 'inline-block',
         float: 'left',
         width: width,
         height: width}"
           v-else-if="item.type === 3">
        <img v-if="PreFileUrl" class="preview-img" :src="PreFileUrl" :style="{ width: width, height: height}"/>
        <div v-else
             :style="{background: '#f5b904',
         width: width,
         height: width,
         'line-height': width}"
             class='fileType'>MP4</div>
      </div>

      <!--是否固定显示文件夹-->
      <div
        v-else-if="item.documentClassify"
        :style="{width: width, height: width}"
        class="documentClassify relative"><i class="iconfont icon-folder"></i></div>

      <!--显示普通文件-->
      <div v-else :style="{background: item.bgColor,
         width: width,
         height: width,
         lineHeight: width}"
         @click="preview"
         class='fileType'>{{item | type}}</div>

      <!--需不需要显示右侧操作栏-->
      <div class="fileInfo" v-if="info && item.type !== 2 && item.type !== 1">
        <small
          class="fileInfo-name"
          v-tooltip="`${item.fileDescribing || item.name}`">
          {{item.fileDescribing || item.name}}({{item.fileSize | formatSize}})
        </small>
        <p class="fileInfo-op" v-if="item.type !== 2">
          <small class="download" @click="downFile(item)">下载</small>
          <small class="preview" @click="preview" v-if="isPreview">{{item.typeText}}</small>
        </p>
      </div>

    </div>

  </div>
</template>

<script>
  import { mapGetters } from 'vuex'
  export default {
    name: 'zz-preview',
    data () {
      return {
        src: '',
        soundSrc: '',
        imageSourceHeight: '',
        PreFileUrl: '',
        isPreview: false,
        clientWidth: '100%',
        clientHeight: 'auth',
        clientTop: '0',
        clientLeft: '0',
        index: 0,
        target: {},
        isConstData: false,
        type: new Set(['jpeg', 'jpg', 'png', 'gif'])
      }
    },
    props: {
      item: {
        type: [Object, Number]
      },
      // 是否一次打开多张图片
      items: {
        type: Array,
        default: function () {
          return []
        }
      },
      block: {
        type: String,
        default: 'inline-block'
      },
      margin: {
        type: String,
        default: '0 5px 0 0'
      },
      // 是否显示左边信息
      info: {
        type: Boolean,
        default: false
      },
      // 是否单独设置图片宽度
      imgWidth: {
        type: String,
        default: ''
      },
      // 图片和图标宽度
      width: {
        type: String,
        default: '40px'
      },
      // 图片和图标高度
      height: {
        type: String,
        default: '40px'
      },
      // 图片是否自适应
      isAuth: {
        type: Boolean,
        default: false
      },
      // 是否有多张图片
      multiple: {
        type: Boolean,
        default: false
      },
      // 是否只显示默认图片
      isConst: {
        type: Boolean,
        default: false
      },
      // 是否填充
      isFilling: {
        type: Boolean,
        default: false
      },
      // 是否开启预览
      isPropsPreview: {
        type: Boolean,
        default: true
      },
      // 图片质量
      th: {
        type: Number,
        default: 4
      },
      // 模型视口
      isPort: {
        type: Boolean,
        default: false
      }
    },
    computed: {
      ...mapGetters({
        fileListSource: 'getFileListSource'
      })
    },
    watch: {
      item () {
        this.isConstData = this.isConst
        this.ready()
      },
      height (value) {
        this.imageSourceHeight = value
        this.$nextTick(() => {
          if (this.multiple || this.isFilling) {
            this.imgFilling()
          }
        })
      }
    },
    filters: {
      type (item) {
        if (item) {
          let fileName = item.name || item.fileName || item.docName
          const length = fileName.lastIndexOf('.')
          return fileName.slice(length + 1)
        }
      }
    },
    created () {
      this.isConstData = this.isConst
      this.previewImageThrottle = this.$Throttle(this.previewImage, 1000)
      this.ready()
    },
    methods: {
      ready () {
        if (!(Object.prototype.toString.call(this.item) === '[object Undefined]')) {
          this.setAuthImage()
          this.getSourceImg()
          if (!this.isConstData) {
            this.computedType()
            this.isPreviewHandle()
          }
        }
      },
      setAuthImage () {
        if (this.isAuth) {
          if (this.multiple) {
            this.imageSourceHeight = this.imgWidth || this.height
          } else {
            this.imageSourceHeight = 'auth'
          }
        } else {
          this.imageSourceHeight = this.imgWidth || this.height
        }
      },
      imgOnload (e) {
        if (this.multiple || this.isFilling) {
          this.target = e.target
          this.imgFilling()
        }
      },
      imgFilling () {
        const {clientHeight, clientWidth} = this.target
        const rect = this.$refs.image.getBoundingClientRect()
        if (clientHeight >= rect.height) {
          this.clientTop = `-${(clientHeight - rect.height) / 2}px`
        } else {
          this.clientHeight = `${rect.height}px`
          const clientWidthCom = clientWidth * rect.height / clientHeight
          this.clientWidth = `${clientWidthCom}px`
          this.clientLeft = `-${(clientWidthCom - rect.width) / 2}px`
        }
      },
      computedType () {
        switch (this.item.type) {
          case 1:
            this.item.typeText = '预览'
            break
          case 2:
            this.previewSound()
            this.item.typeText = '播放'
            break
          case 3:
            this.getPreFileUrl()
            this.item.typeText = '播放'
            break
          case 4:
            this.item.typeText = '预览'
            let fileName = this.item.name || this.item.fileName || this.item.docName
            const url = fileName.slice(fileName.lastIndexOf('.') + 1).toLowerCase()
            this.item.bgColor = this.$IconColor(url)
            break
          default:
            this.item.documentClassify = true
        }
      },
      getSourceImg () {
        if (this.item.type === 1) {
          this.isConstData = false
          this.$store.dispatch({
            type: 'downFile',
            fileUuid: this.item.fileUuid,
            th: this.th
          }).then(res => {
            this.src = res
          }, () => {
            this.$message.error('获取下载地址出错')
          })
        }
      },
      // 获取预览视频截图
      getPreFileUrl () {
        if (this.item.preFileUrl) {
          this.$store.dispatch({
            type: 'downFile',
            fileUuid: this.item.preFileUrl,
            th: 1
          }).then(res => {
            // Success handle
            this.PreFileUrl = res
          }, err => {
            // Error handle
            this.$message.error(err)
          })
        }
      },
      // 是否可以预览
      isPreviewHandle () {
        if (this.item.type === 4) {
          this.isPreview = this.$previewFile(this.item)
        } else {
          this.isPreview = true
        }
      },
      downFile () {
        this.$Download(this.item.fileUuid)
      },
      // 预览文件
      preview () {
        // 1s内只能点击一次
        if (this.clicked) return
        this.clicked = true
        let that = this
        setTimeout(() => {
          that.clicked = false
        }, 1000)
        if (this.isPropsPreview) {
          if (this.isPort) {
            this.$emit('port')
          }
          switch (this.item.type) {
            case 1:
              this.previewImageThrottle()
              break
            case 2:
              break
            case 3:
              this.$video.open(this.item.url)
              break
            case 4:
              if (this.isPreview) {
                this.$pdf.open(this.item.fileUuid)
              }
              break
          }
        }
      },
      // 获取音频文件
      previewSound () {
        this.item.url = `${this.item.url}.mp3`
        this.$store.dispatch({
          type: 'downFile',
          fileUuid: this.item.fileUuid,
          th: 1
        }).then(res => {
          this.soundSrc = res
        }, err => {
          this.$message.error(err)
        })
      },
      previewImage () {
        const images = this.previewImageList()
        this.imagesOnload(images)
      },
      previewImageList () {
        let list = []
        this.$store.commit('showLoading')
        if (this.items.length > 0) {
          list = this.items.map((item, i) => {
            if (this.item.fileUuid === item.fileUuid) {
              this.index = i
            }
            return item
          })
        } else {
          list.unshift(this.item)
        }
        return list
      },
      async imagesOnload (images) {
        const loadData = data => new Promise(resolve => {
          this.$store.dispatch({
            type: 'downFile',
            fileUuid: data.fileUuid,
            th: 1
          }).then(res => {
            const image = new Image()
            image.src = res
            image.onload = () => {
              data.src = res
              data.w = image.width
              data.h = image.height
              resolve(data)
            }
          })
        })
        const arr = []
        for (let i = 0; i < images.length; i++) {
          const data = await loadData(images[i])
          arr.push(data)
        }
        this.$store.commit('hideLoading')
        this.$preview.open(this.index, arr)
      },
      deleteFile (item) {
        this.$emit('handle', item)
      }
    }
  }
</script>

<style lang="scss" scoped>
  .source-img{
    .source-icon{
      text-align: center;
      color: #fff;
      i{
        font-size: 2rem;
      }
    }
    &:last-child{
      margin-right: 0;
    }
    .viewPosition{
      position: absolute;
      right: 0;
      top: 0;
    }
    .fileType{
      color: #fff;
      float: left;
      font-size: 1em;
      text-align: center;
      margin-right: 5px;
      overflow: hidden;
      img{
        width: 100%;
      }
      &:last-child{
        margin-right: 0;
      }
    }
    .table-preview{
      float: left;
      margin-left: 1rem;
    }
    .fileInfo{
      float: left;
      margin-left: 5px;
      small{
        font-size: 0.7rem;
      }
      .fileInfo-op{
        margin: 0;
        color: $color-grid;
      }
      .fileInfo-name{
        width: 150px;
        height: 17px;
        display: inline-block;
        margin-top: 3px;
        color: $color-font;
        @include ellipsis
      }
      .download{
        cursor: pointer;
        margin-top: 5px;
        &:hover{
          color: $color;
        }
      }
      .preview{
        cursor: pointer;
        margin: 5px 0 0 20px;
        &:hover{
          color: $color;
        }
      }
    }
    .documentClassify{
      background: #fff;
      overflow: hidden;
    }
  }
</style>
